package com.company.project.wechat.commom;

import java.io.Writer;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;


import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;

/**
 * xml转换工具
 * @author ZYF
 * @date 2021/5/18 11:03
 */
public class XStreamUtil {
    private static String PREFIX_CDATA = "<![CDATA[";
    private static String SUFFIX_CDATA = "]]>";

    /**
     * 全部转化
     */
    public static XStream initXStream() {
        return new XStream(new XppDriver() {
            @Override
            public HierarchicalStreamWriter createWriter(Writer out) {

                return new PrettyPrintWriter(out) {
                    protected void writeText(QuickWriter writer, String text) {
                        // if (text.startsWith(PREFIX_CDATA) &&
                        // text.endsWith(SUFFIX_CDATA)) {
                        writer.write(PREFIX_CDATA + text + SUFFIX_CDATA);
                        // } else {
                        // super.writeText(writer, text);
                        // }
                    }
                };
            }
        });
    }

    /**
     *
     * <P>标题：通用全部转化,仅转化string为 <![CDATA[文本内容]]></p>
     * @author zyf
     * @param obj
     * @return
     */
    public static String ToXml(Object obj) {
        XStream xstream = XStreamUtil.initXStream();
        xstream.alias("xml", obj.getClass());
        return trimXml(xstream.toXML(obj));
    }

    /**
     * 去掉xml多余的空白、换行符
     */
    public static String trimXml(String xml) {
        String result = xml;
        if (null != result) {
            result = result.replaceAll(">\\s+<", "><");
        }
        return result;
    }

    /**
     * 初始化XStream可支持某一字段可以加入CDATA标签,如果需要某一字段使用原文,就需要在String类型的text的头加上
     * "<![CDATA["和结尾处加上"]]>"标签， 以供XStream输出时进行识别
     * @author zyf
     * @param isAddCDATA
     *  是否支持CDATA标签
     */
    public static XStream initXStream(boolean isAddCDATA) {
        XStream xstream = null;
        if (isAddCDATA) {
            xstream = new XStream(new XppDriver() {
                @Override
                public HierarchicalStreamWriter createWriter(Writer out) {
                    return new PrettyPrintWriter(out) {
                        protected void writeText(QuickWriter writer, String text) {
                            if (text.startsWith(PREFIX_CDATA) && text.endsWith(SUFFIX_CDATA)) {
                                writer.write(text);
                            } else {
                                super.writeText(writer, text);
                            }
                        }
                    };
                }
            });
        } else {
            xstream = new XStream();
        }
        return xstream;
    }

    /**
     *
     * <P>标题：xml字符串转对象</p>
     * @author zyf
     * @param xml
     * @return
     */
    public static String xmlToJson(String xml) {
        String str = "";
        Document doc = null;
        try {
            doc = DocumentHelper.parseText(xml); // 将字符串转为XML
            Element rootElt = doc.getRootElement(); // 获取根节点
            @SuppressWarnings("unchecked")
            List<Element> list = rootElt.elements();// 获取根节点下所有节点
            str+="{";
            for (Element element : list) { // 遍历节点
                str+=",\""+element.getName()+"\":\""+element.getText()+"\"";
            }
            str+="}";
            str=str.replaceFirst(",", "");
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str;
    }

}